package naga.x.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import naga.x.game.time.TimeUpdater;

public class TimeUtils {
	
//	public static final long TIME_OFFSET = 0;

	/**
	 * 获取今天凌晨时刻
	 * @return
	 */
	public static long getTodayZeroTime() {
		return getTodayZeroTimeCalendar().getTimeInMillis();
	}
	
	public static Date getTodayZeroTimeDate() {
		return getTodayZeroTimeCalendar().getTime();
	}
	
	public static Calendar getTodayZeroTimeCalendar() {
		return getZeroTimeCalendarOf(TimeUpdater.getInstance().now());
	}
	
	public static long getZeroTimeOf(long time) {
		return getZeroTimeCalendarOf(time).getTimeInMillis();
	}
	
	public static Date getZeroTimeDateOf(long time) {
		return getZeroTimeCalendarOf(time).getTime();
	}
	
	/**
	 * 获取某个时间当天的凌晨时刻
	 * @param time
	 * @return
	 */
	public static Calendar getZeroTimeCalendarOf(long time) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal;
	}
	
	/**
	 * 获取本周一凌晨时刻
	 * @param time
	 * @return
	 */
	public static long getMondayZeroTime() {
		return getMondayZeroTimeCalendar().getTimeInMillis();
	}
	
	public static Date getMondayZeroTimeDate() {
		return getMondayZeroTimeCalendar().getTime();
	}
	
	public static Calendar getMondayZeroTimeCalendar() {
		return getMondayZeroTimeCalendar(TimeUpdater.getInstance().now());
	}
	
	public static long getMondayZeroTime(long time) {
		return getMondayZeroTimeCalendar(time).getTimeInMillis();
	}
	
	public static Date getMondayZeroTimeDate(long time) {
		return getMondayZeroTimeCalendar(time).getTime();
	}
	
	/**
	 * 获取某个时间的周一凌晨时间
	 * @param time
	 * @return
	 */
	public static Calendar getMondayZeroTimeCalendar(long time) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		int day = cal.get(Calendar.DAY_OF_WEEK);
		// (-6~0) 周日(=1)需要特殊处理
		int dayoffset = day == Calendar.SUNDAY ? -6 : Calendar.MONDAY - day;
		cal.add(Calendar.DAY_OF_YEAR, dayoffset);
		return cal;
	}
	
	/**
	 * 得到某个时间(time1)的当天的某时刻(targetHour:targetMinute)
	 * @param nowTime
	 * @param targetHour
	 * @param targetMinute
	 * @return
	 */
	public static long getTodayTimeMillis(long nowTime, int targetHour, int targetMinute){
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(nowTime);
		cal.set(Calendar.HOUR_OF_DAY, targetHour);
		cal.set(Calendar.MINUTE, targetMinute);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTimeInMillis();
	}
	
	public static long offsetToMillis(Date date, Date offset, int... fields) {
		return offset(date, offset, fields).getTime();
	}
	
	public static Date offset(Date date, Date offset, int... fields) {
		if (fields == null || fields.length == 0) {
			return date;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		
		Calendar off = Calendar.getInstance();
		off.setTime(offset);
		// yyyy-MM-dd HH:mm:ss:SSS
		for (int f : fields) {
			int val = off.get(f);
			if (val != 0) {
				cal.add(f, val);
			}
		}
		return cal.getTime();
	}
	
	public static String format(long time) {
		return format(new Date(time));
	}
	
	public static String format(Date date) {
		return format("yyyy-MM-dd HH:mm:ss", date);
	}
	
	public static String format(String pattern, long time) {
		return format(pattern, new Date(time));
	}
	
	public static String format(String pattern, Date date) {
		DateFormat df = new SimpleDateFormat(pattern);
		return df.format(date);
	}
	
	public static Date parse(String date) {
		return parse("yyyy-MM-dd HH:mm:ss", date);
	}
	
	public static Date parse(String pattern, String date) {
		DateFormat df = new SimpleDateFormat(pattern);
		try {
			return df.parse(date);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static long getRecentTime(Date date1, Date date2) {
		Date d = getRecentDate(date1, date2);
		return d != null ? d.getTime() : 0L;
	}
	
	public static Date getRecentDate(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return null;
		}
		if (date1 == null) {
			return date2;
		}
		if (date2 == null) {
			return date1;
		}
		return date1.getTime() > date2.getTime() ? date1 : date2;
	}
	
	public static long diffMillis(Date date1, Date date2) {
		long t1 = date1 != null ? date1.getTime() : 0L;
		long t2 = date2 != null ? date2.getTime() : 0L;
		return diffMillis(t1, t2);
	}
	
	public static long diffMillis(Date date1, long t2) {
		return diffMillis(date1 != null ? date1.getTime() : 0, t2);
	}
	
	public static long diffMillis(long t1, long t2) {
		return Math.abs(t1 - t2);
	}
	
	public static int diffDay(Date date1, Date date2) {
		long millis = diffMillis(date1, date2);
		return (int) TimeUnit.MILLISECONDS.toDays(millis);
	}
	
	public static int diffDay(Date date1, long t2) {
		long millis = diffMillis(date1, t2);
		return (int) TimeUnit.MILLISECONDS.toDays(millis);
	}
	
	public static int diffDay(long t1, long t2) {
		long millis = diffMillis(t1, t2);
		return (int) TimeUnit.MILLISECONDS.toDays(millis);
	}
	
	public static int ofDay(long time) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		return (cal.get(Calendar.YEAR) << 16) | cal.get(Calendar.DAY_OF_YEAR);
	}

	public static int getMoon(long time){
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		return cal.get(Calendar.MONTH);
	}
	
	public static int getMoonMaxDay(long time){
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
	}
	
	public static int getYear(long time){
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);
		return cal.get(Calendar.YEAR);
	}
	/**
	 * day2 < day1 + diff
	 * 对比天数差 检测day2是否在day1后的diff天内 单位天
	 */
	public static boolean checkDayDuring(int day1, int day2, int diff){
		int y1 = day1 >> 16;
		int y2 = day2 >> 16;
		if(y1 == y2){
			if(day2 < day1 + diff){
				return true;
			}
		}else{
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.YEAR, y1);
			cal.set(Calendar.DAY_OF_YEAR, day1 & 0xFFFF);
			long time1 = cal.getTimeInMillis();
			cal.set(Calendar.YEAR, y2);
			cal.set(Calendar.DAY_OF_YEAR, day2 & 0xFFFF);
			long time2 = cal.getTimeInMillis();
			if(time2 < time1 + diff * 86400000){//24 * 3600 * 1000
				return true;
			}
		}
		return false;
	}
	/**
	 * @return endDay - startDay
	 */
	public static int getDayGap(int startDay, int endDay){
		int y1 = startDay >> 16;
		int y2 = endDay >> 16;
		if(y1 == y2){
			return endDay - startDay;
		}else{
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.YEAR, y1);
			cal.set(Calendar.DAY_OF_YEAR, startDay & 0xFFFF);
			long time1 = cal.getTimeInMillis();
			cal.set(Calendar.YEAR, y2);
			cal.set(Calendar.DAY_OF_YEAR, endDay & 0xFFFF);
			long time2 = cal.getTimeInMillis();
			return (int) ((time2 - time1)/86400000);
		}
	}
	
	/**
	 * 得到当日的周一的day
	 * @return
	 */
	public static int getMonday(int today){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, today >> 16);
		cal.set(Calendar.DAY_OF_YEAR, today & 0xFFFF);
		int monday = today;
		int thisWeekDay = (cal.get(Calendar.DAY_OF_WEEK) + 5) % 7;//0~6
		if((today & 0xFFFF) < 8){//第一周特殊处理
			cal.add(Calendar.DAY_OF_MONTH, -thisWeekDay);
			monday = cal.get(Calendar.YEAR) << 16 | cal.get(Calendar.DAY_OF_YEAR);
		}else{
			monday = today - thisWeekDay;
		}
		return monday;
	}
	
}
